package com.suyang.syt.aop;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.suyang.syt.dao.interfaces.OperateLogDao;
import com.suyang.syt.model.OperateLog;
import com.suyang.syt.model.User;
import com.suyang.syt.util.DateFormat;

public class OperateLogAspect {

	private Logger logger = Logger.getLogger(OperateLogAspect.class);

	@Autowired
	private OperateLogDao operateLogDao;

	public void log(JoinPoint joinPoint) throws Exception {
		ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if (sra != null) {
			HttpServletRequest request = sra.getRequest();
			if (request != null) {
				User user = (User) request.getSession().getAttribute("loginUser");
				OperateLog operateLog = new OperateLog();
				if (user != null) {
					operateLog.setCreateName(user.getUsername());
				}
				operateLog.setIp(request.getRemoteAddr());
				operateLog.setCreateTime(DateFormat.dateToString(new Date()));
				String controller = joinPoint.getTarget().toString();
				String controllerName = controller.substring(controller.lastIndexOf(".") + 1, controller.indexOf("@"));
				// 获取方法名
				String methodName = joinPoint.getSignature().getName();
				String operateContent = getOptionContent(joinPoint.getArgs(), methodName);
				// operateLog.setAction(controllerName + "." +
				// joinPoint.getSignature().getName() + "(" +
				// joinPoint.getArgs().length + ")");
				operateLog.setAction(operateContent);
				if (methodName.startsWith("add")) {
					operateLog.setOperate("增加");
				} else if (methodName.startsWith("delete")) {
					operateLog.setOperate("删除");
				} else if (methodName.startsWith("update")) {
					if (methodName.startsWith("updateLogin")) {
						operateLog.setAction(request.getAttribute("username") + " 进行登陆");
						operateLog.setOperate("登陆");
					} else {
						operateLog.setOperate("更新");
					}
				}

				if ("UserServiceImpl.updateLogin(2)".equals(operateLog.getAction())) {
					operateLog.setCreateName(String.valueOf(joinPoint.getArgs()[0]));
				}
				operateLogDao.add(operateLog);
			}
		}
	}

	public void logException(JoinPoint joinPoint, Throwable ex) {
		ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if (sra != null) {
			HttpServletRequest request = sra.getRequest();
			if (request != null && ex != null) {
				OperateLog operateLog = new OperateLog();
				User user = (User) request.getSession().getAttribute("loginUser");
				if (user != null) {
					operateLog.setCreateName(user.getUsername());
				}
				operateLog.setIp(request.getRemoteAddr());
				operateLog.setCreateTime(DateFormat.dateToString(new Date()));
				operateLog.setException(ex.toString());
				operateLog.setStatus(1);
				String controller = joinPoint.getTarget().toString();
				String controllerName = controller.substring(controller.lastIndexOf(".") + 1, controller.indexOf("@"));
				operateLog.setAction(controllerName + "." + joinPoint.getSignature().getName() + "(" + joinPoint.getArgs().length + ")");
				if ("UserServiceImpl.updateLogin(2)".equals(operateLog.getAction())) {
					operateLog.setCreateName(String.valueOf(joinPoint.getArgs()[0]));
				}
				OperateLogAspectUtil.addLogException(operateLog);
				logger.error(ex.getMessage(), ex);
			}
		}
	}

	/**
	 * 使用Java反射来获取被拦截方法(insert、update)的参数值， 将参数值拼接为操作内容
	 */
	public String getOptionContent(Object[] args, String mName) throws Exception {
		if (args == null) {
			return null;
		}
		StringBuffer rs = new StringBuffer();
		rs.append(mName);
		String className = null;
		int index = 1;
		// 遍历参数对象
		for (Object info : args) {

			// 获取对象类型
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			rs.append("[参数" + index + "，类型：" + className + "，值：");
			// 获取对象的所有方法
			Method[] methods = info.getClass().getDeclaredMethods();
			// 遍历方法，判断get方法
			for (Method method : methods) {
				String methodName = method.getName();
				// 判断是不是get方法
				if (methodName.indexOf("get") == -1) {// 不是get方法
					continue;// 不处理
				}
				Object rsValue = null;
				try {
					// 调用get方法，获取返回值
					rsValue = method.invoke(info);
					if (rsValue == null) {// 没有返回值
						continue;
					}
				} catch (Exception e) {
					continue;
				}
				// 将值加入内容中
				rs.append("(" + methodName + " : " + rsValue + ")");
			}
			rs.append("]");
			index++;
		}

		return rs.toString();
	}

}
